const fs = require('fs')
const path = require('path')

module.exports = function HtmlCacheFix(options) {
  let { mode, crossOrigin, charsetFix, assetsDir: defaultAssetsDir, assetsList } = options || {}, res = []
  mode = ['ajax', 'jsonp'].includes(mode) ? mode : 'ajax'
  crossOrigin = mode == 'ajax' ? true : crossOrigin || false
  charsetFix = charsetFix == null || charsetFix == true ? 'utf-8' : charsetFix
  defaultAssetsDir = defaultAssetsDir == null ? 'dist' : defaultAssetsDir
  assetsList = assetsList && assetsList.length ? assetsList : [options || {}]
  for (let i = 0, l = assetsList.length, cwd = process.cwd(); i < l; i++) {
    if (!assetsList[i]) continue
    let { assetsDir, sourcePath, targetPath, referPath } = assetsList[i], targetData = ''
    assetsDir = path.resolve(cwd, path.join('.', assetsDir == null ? defaultAssetsDir : assetsDir))
    sourcePath = path.join('.', sourcePath || 'index.html')
    targetPath = path.join('.', targetPath || sourcePath.replace(/(\..*?|)$/, '-source$1'))
    mode == 'jsonp' && (targetPath = targetPath.replace(/(\..*?|)$/, '.js'))
    referPath = (referPath || path.join(path.relative(path.dirname(sourcePath), path.dirname(targetPath)), path.basename(targetPath))).replace(/\\/g, '/')
    sourcePath = path.join(assetsDir, sourcePath)
    targetPath = path.join(assetsDir, targetPath)
    if (res.some(v => v.sourcePath === sourcePath)) continue
    if (!fs.existsSync(path.dirname(targetPath))) fs.mkdirSync(path.dirname(targetPath), { recursive: true })
    if (!fs.existsSync(sourcePath)) {
      console.warn(`[HtmlCacheFix Warn] Source path "${sourcePath}" raw file is not exist.`)
      if (!fs.existsSync(path.dirname(sourcePath))) fs.mkdirSync(path.dirname(sourcePath), { recursive: true })
    } else {
      targetData = fs.readFileSync(sourcePath, 'utf8')
      if (!targetData) {
        console.warn(`[HtmlCacheFix Warn] Source path "${sourcePath}" raw file has no content.`)
      } else if (charsetFix) {
        targetData = targetData.replace(/(<script)(?![^>]*charset=)(?=.*?>)/g, `$1 charset="${charsetFix}"`)
      }
    }
    if (mode == 'jsonp') {
      if (targetData) targetData = `document.write('${targetData.replace(/\s*[\r\n]\s*/g, '\\n').replace(/'/g, "\\'")}');`
      targetData = `setTimeout(function(){document.open();${targetData}document.close();});`
    }
    let sourceData =
      `<!DOCTYPE html><html><head>
        ${charsetFix ? `<meta charset="${charsetFix}">` : ''}
        <script>${mode == 'jsonp'
          ? `document.write('<script${crossOrigin ? ' crossorigin' : ''} src="${referPath}?v='+new Date().getTime()+'"><\\/script>');`
          : `(function () {
            var a = new XMLHttpRequest();
            a.open('GET', '${referPath.replace(/'/g, "\\'")}');
            a.setRequestHeader('Cache-Control', 'no-cache');
            a.onload = function () {
              document.open();
              document.write(a.responseText);
              document.close();
            };
            a.send();
          })();`
        }</script>
      </head></html>`.replace(/\s*[\r\n]\s*/g, '')
    fs.writeFileSync(sourcePath, sourceData, 'utf8')
    fs.writeFileSync(targetPath, targetData, 'utf8')
    res.push({ sourcePath, targetPath })
  }
  return res
}
